﻿<cfsilent>

	<cfscript>

		jsonAdvice = getProperty("serviceFactory").getBean("jsonAdvice");
		
		mathAdvice = getProperty("serviceFactory").getBean("senateMathAdvice");
		taskProp = getProperty("serviceFactory").getBean("taskPropertyAdvice");
		sequenceTaskTimeTable = getProperty("serviceFactory").getBean("sequenceTaskTimeTable");
		sequenceTeacherTimeRable =  getProperty("serviceFactory").getBean("sequenceTeacherTimeTable");
		sequenceClassroomTimeTable =  getProperty("serviceFactory").getBean("sequenceClassroomTimeTable");
		
		response = structNew();
		structInsert(response, "success", false, true);

		taskId = event.getArg("TSK");
		taskType = event.getArg("TT");

		weekDay = event.getArg("wkday");
		lectureId = event.getArg("lec");
		cells = event.getArg("n");

		cellStart = mathAdvice.convertLectureIdxToCellStart(lectureId);
		cellEnd = cellStart + cells -1;
	
		transaction {
			
			/* 载入教学任务 */
			switch(taskType){
				case 'P':
					sql = "SELECT  a.task_week,a.task_limite,
									a.cr_type,a.campus_id,
									a.term_id,b.course_name,
									a.tch_id,a.cid,
									a.task_prop,a.task_time,
									a.task_place,a.task_capacity 
							FROM t_task a 
                   				INNER JOIN t_course b ON b.cid = a.cid 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'C':
					sql = "SELECT  a.task_week,a.task_limite,
									a.cr_type,a.campus_id,
									a.term_id,b.course_name,
									a.tch_id,a.cid,
									a.task_prop,a.task_time,
									a.task_place,a.task_capacity 
							FROM t_common_task a 
                   				INNER JOIN t_course b ON b.cid = a.cid 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'R':
					sql = "SELECT  a.task_week,a.task_limite,
									a.cr_type,a.campus_id,
									a.term_id,b.course_name,
									a.tch_id,a.cid,
									a.task_prop,a.task_time,
									a.task_place,a.task_capacity 
							FROM t_reopen_task a 
                   				INNER JOIN t_course b ON b.cid = a.cid 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'T':
					sql = "SELECT  a.task_week,a.task_limite,
									a.cr_type,a.campus_id,
									a.term_id,b.course_name,
									a.tch_id,a.cid,
									a.task_prop,a.task_time,
									a.task_place,a.task_capacity 
							FROM t_sport_task a 
                   				INNER JOIN t_course b ON b.cid = a.cid 
							WHERE a.tsk_id = :taskId  ";
					break;
			}
			queryObj = new Query(datasource = application.dnsMaster);
			queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
			rs_task = queryObj.execute(sql = sql).getResult();
			
			/* 读取学期设置 */
			termId = rs_task.term_id;
			
			/* 载入排课任务 */
			sql = "SELECT  a.task_id,a.period_done,
						   a.period_need 
					FROM t_task_arrange a 
					WHERE a.task_id = :taskId ";
					
			queryObj = new Query(datasource = application.dnsMaster);
			queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
			rs_taskArrange = queryObj.execute(sql = sql).getResult();
			
			/* 计算周次序列和已排周学时 */
			taskWeek = listToArray(rs_task.task_week, "-");
			periodWeeks = int(taskWeek[2]) - int(taskWeek[1]) + 1;
			
			weekIdx = mathAdvice.convertWeekIdx(rs_task.task_week);
			
			/* 检查是否有可用教室 */
			
			courseSize = rs_task.task_limite;
			clsroomType = rs_task.cr_type;
			campusId = rs_task.campus_id;
			
			i=0;
			conHSQL = " ";
			for (i=int(taskWeek[1]); i lte int(taskWeek[2]); i++) {
				conHSQL = conHSQL & "SUBSTR(b.widx, " & i & ", 1) = '1' ";
				if (i lt int(taskWeek[2])) {
				conHSQL = conHSQL & " or ";
				}
			}
			
			
			/**
			*取消教室人数限制
			*AND 
			  (
			  a.sits_course > :courseSize 
			  OR 
			  a.sits_course = :courseSize 
			  ) 
			*/
			sql = "SELECT a.cr_id  
					FROM t_classroom a
					WHERE 
						SUBSTR(a.cr_usage, 2, 1) = '1' 
						AND 
						a.cr_type = :clsroomType 
						AND
						a.campus_id = :campusId 
						AND 
						NOT EXISTS (
							SELECT 1 
							FROM t_clsroom_timetable b
							WHERE 
								a.cr_id = b.cr_id
								AND 
								b.term_id = :termId 
								AND 
								b.wdidx = :weekDay 
								AND
								NOT ( b.cellidx + b.cellrelay -1 < :cellStart 
								OR 
								b.cellidx > :cellEnd 
								) 
								AND 
								("&conHSQL&")
						)
					ORDER BY a.sits_course ASC, a.classroom ASC";
					
			queryObj = new Query(datasource = application.dnsMaster,maxRows = 1);
			queryObj.addParam(name ="courseSize", value=courseSize, cfsqltype="cf_sql_interger");
			queryObj.addParam(name ="termId", value=termId, cfsqltype="cf_sql_char");
			queryObj.addParam(name ="weekDay", value=wkday, cfsqltype="cf_sql_char");
			queryObj.addParam(name ="cellStart", value=cellStart, cfsqltype="cf_sql_interger");
			queryObj.addParam(name ="cellEnd", value=cellEnd, cfsqltype="cf_sql_interger");
			queryObj.addParam(name ="clsroomType", value=clsroomType, cfsqltype="cf_sql_char");
			queryObj.addParam(name ="campusId", value=campusId, cfsqltype="cf_sql_char");
			rs_clsroomCheck = queryObj.execute(sql = sql).getResult();
			
			if (rs_clsroomCheck.recordCount) {
				
				/* 有可用教室 */
				sql = "SELECT  a.classroom,a.cr_id,
							   a.sits_course
						FROM t_classroom a 
						WHERE a.cr_id = :classroomId ";
						
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="classroomId", value=rs_clsroomCheck["cr_id"][1], cfsqltype="cf_sql_char");
				rs_classRoom = queryObj.execute(sql = sql).getResult();
				
				/* 生成新的时间序列 */
				
				sequenceTaskTimeTable.setTaskID(rs_taskArrange.task_id);
				timeIdx = sequenceTaskTimeTable.getTimeIDX();
				sequenceTaskTimeTable.setTimeIndex(timeIdx);
				timeId = sequenceTaskTimeTable.getID();
				
				sql = "INSERT INTO t_task_timetable (
							   task_id,
							   widx,
							   wdidx,
							   cellidx,
							   cellrelay,
							   tasktime,
							   taskclsroom,
							   task_week,
							   tasktime_id,
							   tidx
					) VALUES (
								:TaskArrange ,
								:WeekIndex ,
								:WeekDay ,
								:CellStart ,
								:CellLength ,
								:TaskClassTime ,
								:TaskClassRoom ,
								:TaskWeek ,
								:TaskTimeID ,
								:TimeIndex 
					)  "; 
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="TaskArrange", value=rs_taskArrange.task_id, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="WeekIndex", value=weekIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="WeekDay", value=weekDay, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="CellStart", value=cellStart, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="CellLength", value=cells, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="TaskClassTime", value=weekDay &"@"& lectureId & "-" & cells, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskClassRoom", value=rs_classRoom.classroom, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskWeek", value=rs_task.task_week, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskTimeID", value=timeId, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TimeIndex", value=timeIdx, cfsqltype="cf_sql_char");
				queryObj.execute(sql = sql);

				/* 生成教室时间占用表 */
				sequenceClassroomTimeTable.setTermID(rs_task.term_id);
				sequenceClassroomTimeTable.setClassroomID(rs_classRoom.cr_id);
				useIdx = sequenceClassroomTimeTable.getIDX();
				sequenceClassroomTimeTable.setIndex(useIdx);
				useId = sequenceClassroomTimeTable.getID();
				
				
				sql = "INSERT INTO t_clsroom_timetable a 
						(
							   a.crtime_id,
							   a.uidx,
							   a.widx,
							   a.wdidx,
							   a.cellidx,
							   a.cellrelay,
							   a.term_id,
							   a.cr_id,
							   a.ut_id
						)VALUES(
							   :ClassRoomTimeID ,
							   :UseIndex ,
							   :WeekIndex ,
							   :WeekDay ,
							   :CellStart ,
							   :CellLength ,
							   :Term ,
							   :ClassRoom ,
							   :Usage 
						)";
				
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="ClassRoomTimeID", value=useId, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="WeekIndex", value=weekIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="WeekDay", value=weekDay, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="CellStart", value=cellStart, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="CellLength", value=cells, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="UseIndex", value=useIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="Term", value=rs_task.term_id, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="ClassRoom", value=rs_classRoom.cr_id, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="Usage", value="1", cfsqltype="cf_sql_char");
				queryObj.execute(sql = sql);
				
				sql = "INSERT INTO t_clsroom_forcourse a 
						(
							   a.crtime_id,
							   a.task_id,
							   a.tidx,
							   a.task_type,
							   a.taskclsroom,
							   a.tasktime,
							   a.task_week,
							   a.task_course
						)VALUES(
							   :ClassRoomTimeID ,
							   :TaskID ,
							   :TaskTimeIndex ,
							   :TaskType ,
							   :TaskClassRoom ,
							   :TaskClassTime ,
							   :TaskWeek ,
							   :TaskCourse 
						)";
						
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="ClassRoomTimeID", value=useId, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskID", value=taskId, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskTimeIndex", value=timeIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskType", value=taskType, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskClassRoom", value=rs_classRoom.classroom, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskClassTime", value=weekDay &"@"& lectureId & "-" & cells, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskWeek", value=rs_task.task_week, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskCourse", value=rs_task.course_name, cfsqltype="cf_sql_varchar");
				queryObj.execute(sql = sql);
				
				
				/* 生成教师时间占用表 */
				
				sequenceTeacherTimeRable.setTermID(rs_task.term_id);
				sequenceTeacherTimeRable.setTeacherID(rs_task.tch_id );
				tchTimeIdx = sequenceTeacherTimeRable.getTimeIDX();
				sequenceTeacherTimeRable.setTimeIndex(tchTimeIdx);
				tchTimeId = sequenceTeacherTimeRable.getID();
				
				sql = "INSERT INTO t_teacher_timetable (
							   widx,
							   wdidx,
							   cellidx,
							   cellrelay,
							   task_id,
							   task_type,
							   term_id,
							   tch_id,
							   cid,
							   task_week,
							   tasktime,
							   teachertime_id,
							   tidx,
							   taskclsroom
					) VALUES (
								:WeekIndex ,
								:WeekDay ,
								:CellStart ,
								:CellLength ,
								:TaskID ,
								:TaskType ,
								:Term ,
								:Teacher ,
								:Course ,
								:TaskWeek ,
								:TaskClassTime ,
								:TeacherTimeID ,
								:TimeIndex ,
								:TaskClassRoom 
					)  "; 
					
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="WeekIndex", value=weekIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="WeekDay", value=weekDay, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="CellStart", value=cellStart, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="CellLength", value=cells, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="TaskID", value=taskId, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskType", value=taskType, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="Term", value=rs_task.term_id, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="Teacher", value=rs_task.tch_id, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="Course", value=rs_task.cid, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskWeek", value=rs_task.task_week, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskClassTime", value=weekDay &"@"& lectureId & "-" & cells, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TeacherTimeID", value=tchTimeId, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TimeIndex", value=tchTimeIdx, cfsqltype="cf_sql_char");
				queryObj.addParam(name ="TaskClassRoom", value=rs_classRoom.classroom, cfsqltype="cf_sql_char");
				queryObj.execute(sql = sql);
				
				/* 累计已排周学时 */
				periodDone = rs_taskArrange.period_done + periodWeeks * cells;

				sql = "UPDATE t_task_arrange a 
						SET a.period_done = : periodDone 
						WHERE a.task_id = :taskId ";
						
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="periodDone", value=periodDone, cfsqltype="cf_sql_interger");
				queryObj.execute(sql = sql);
				
				sql = "SELECT  a.task_id,a.period_done,
						   a.period_need 
					FROM t_task_arrange a 
					WHERE a.task_id = :taskId ";
					
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				rs_taskArrangeNow = queryObj.execute(sql = sql).getResult();
				
				TaskProps = rs_task.task_prop;
				/* 如果已排学时已满足排课要求 则锁定排课任务 */
				if (rs_taskArrangeNow.period_done gte rs_taskArrangeNow.period_need) {
					
					taskProp.parseProperty( rs_task.task_prop );
					taskProp.setArrangeDone(true);
					
					TaskProps =  taskProp.stringProperty() ;
				}

				/* 保存已安排时间 */
				taskTime = listAppend(rs_task.task_time, weekDay &"@"& lectureId & "-" & cells, ",");

				/* 保存已安排教室 */
				taskPlace = listAppend(rs_task.task_place, rs_classRoom.classroom, ",");
			
				TaskCapacity = rs_task.task_capacity;
				/* 更新教学班最大排课容量 */
				if (rs_task.task_capacity eq 0) {
					TaskCapacity = rs_classRoom.sits_course;
				}
			
				switch(taskType){
				case 'P':
					sql = "UPDATE t_task a 
							SET a.task_prop = :TaskProps ,
								a.task_time = :taskTime ,
								a.task_place = :TaskPlace ,
								a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'C':
					sql = "UPDATE t_common_task a 
							SET a.task_prop = :TaskProps ,
								a.task_time = :taskTime ,
								a.task_place = :TaskPlace ,
								a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'R':
					sql = "UPDATE t_reopen_task a 
							SET a.task_prop = :TaskProps ,
								a.task_time = :taskTime ,
								a.task_place = :TaskPlace ,
								a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'T':
					sql = "UPDATE t_sport_task a 
							SET a.task_prop = :TaskProps ,
								a.task_time = :taskTime ,
								a.task_place = :TaskPlace ,
								a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				}
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="TaskProps", value=TaskProps, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="taskTime", value=taskTime, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskPlace", value=TaskPlace, cfsqltype="cf_sql_varchar");
				queryObj.addParam(name ="TaskCapacity", value=TaskCapacity, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				queryObj.execute(sql = sql);
			
				

				structInsert(response, "taskID", taskId, true);
				structInsert(response, "weekDay", weekDay, true);
				structInsert(response, "lecture", lectureId, true);
				structInsert(response, "cells", cells, true);
				structInsert(response, "taskTime", taskTime, true);
				structInsert(response, "taskPlace", taskPlace, true);
				
				structInsert(response, "periodDone", rs_taskArrangeNow.period_done, true);
				structInsert(response, "periodNeed", rs_taskArrangeNow.period_need, true);

				structInsert(response, "success", true, true);
				
			}
			else {
				structInsert(response, "reason", "没有可用教室", true);
				structInsert(response, "weekDay", weekDay, true);
				structInsert(response, "lecture", lectureId, true);
			}

		}
		
		transaction {
			
			/* 载入教学任务 */
			switch(taskType){
				case 'P':
					sql = "SELECT 
									a.task_place,a.task_capacity 
							FROM t_task a 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'C':
					sql = "SELECT  
									a.task_place,a.task_capacity 
							FROM t_common_task a 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'R':
					sql = "SELECT 
									a.task_place,a.task_capacity 
							FROM t_reopen_task a 
							WHERE a.tsk_id = :taskId  ";
					break;
				case 'T':
					sql = "SELECT  
									a.task_place,a.task_capacity 
							FROM t_sport_task a 
							WHERE a.tsk_id = :taskId  ";
					break;
			}
			queryObj = new Query(datasource = application.dnsMaster);
			queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
			rs_taskPlace = queryObj.execute(sql = sql).getResult();
			
			TaskCapacity = rs_taskPlace.task_capacity;
			/* 刷新教学班最大容量 */
			if ( rs_taskPlace.task_place eq "" ) {
				/* 如果没有排地点 则恢复容量为默认值 */
				TaskCapacity = 0;
			}
			else {
				/* 从已拍地点中读取最小值 */
				sql = "SELECT 
						min(c.sits_course) sits_course
						FROM t_clsroom_timetable a 
							INNER JOIN t_classroom c ON c.cr_id = a.cr_id 
							INNER JOIN t_clsroom_forcourse cf ON a.crtime_id = cf.crtime_id 
						WHERE cf.task_id  = :taskId ";
						 
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				rs_leftClassroom = queryObj.execute(sql = sql).getResult();
				
				if ( rs_leftClassroom.recordCount ) {
					TaskCapacity = rs_leftClassroom["sits_course"][1];
				}
			} 
			
			switch(taskType){
				case 'P':
					sql = "UPDATE t_task a 
							SET a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'C':
					sql = "UPDATE t_common_task a 
							SET a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'R':
					sql = "UPDATE t_reopen_task a 
							SET a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				case 'T':
					sql = "UPDATE t_sport_task a 
							SET a.task_capacity = :TaskCapacity 
							WHERE a.tsk_id = :taskId ";
					break;
				}
				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="TaskCapacity", value=TaskCapacity, cfsqltype="cf_sql_interger");
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				queryObj.execute(sql = sql);
			
		}
		
	</cfscript>
</cfsilent><cfoutput>#jsonAdvice.encode(data:response, stringNumbers:true)#</cfoutput>